package messages

import (
	"context"
	"encoding/json"
	"errors"
	kitlog "github.com/go-kit/kit/log"
	"github.com/go-kit/kit/transport"
	kithttp "github.com/go-kit/kit/transport/http"
	"github.com/gorilla/mux"
	"net/http"
)

func MakeHandler(s Service, logger kitlog.Logger) http.Handler {
	opts := []kithttp.ServerOption{
		kithttp.ServerErrorHandler(transport.NewLogErrorHandler(logger)),
		kithttp.ServerErrorEncoder(errorEncoder),
	}

	r := mux.NewRouter()
	e := MakeServerEndpoints(s)

	messageSearchHandler := kithttp.NewServer(
		e.MessageSearchEndpoint,
		decodeMessageSearchRequest,
		encodeMessageSearchResponse,
		opts...,
	)

	messageContextHandler := kithttp.NewServer(
		e.MessageContextEndpoint,
		decodeMessageContextRequest,
		encodeMessageContextResponse,
		opts...,
	)

	smartAlarmHandler := kithttp.NewServer(
		e.SmartAlarmEndpoint,
		decodeAlarmMessageRequest,
		encodeAlarmMessageResponse,
		opts...,
	)

	keywordAlarmHandler := kithttp.NewServer(
		e.KeywordAlarmEndpoint,
		decodeAlarmMessageRequest,
		encodeAlarmMessageResponse,
		opts...,
	)

	searchFileHandler := kithttp.NewServer(
		e.SearchFileEndpoint,
		decodeSearchFileRequest,
		encodeSearchFileResponse,
		opts...,
	)

	setTagHandler := kithttp.NewServer(
		e.SetTagEndpoint,
		decodeSetTagRequest,
		encodeSetTagResponse,
		opts...,
	)

	fileTravelHandler := kithttp.NewServer(
		e.SetTagEndpoint,
		decodeFileTravelRequest,
		encodeFileTravelResponse,
		opts...,
	)

	// POST    /api/v1/message/search                     一键搜索消息
	// POST    /api/v1/message/context                    获取消息上下文
	// POST    /api/v1/message/smart_alarm                获取智能预警消息
	// POST    /api/v1/message/keyword_alarm              获取关键词预警消息

	r.Methods("POST").Path(`/api/v1/message/search`).Handler(messageSearchHandler)
	r.Methods("POST").Path(`/api/v1/message/context`).Handler(messageContextHandler)
	r.Methods("POST").Path(`/api/v1/message/smart_alarm`).Handler(smartAlarmHandler)
	r.Methods("POST").Path(`/api/v1/message/keyword_alarm`).Handler(keywordAlarmHandler)
	r.Methods("POST").Path(`/api/v1/message/file/search`).Handler(searchFileHandler)
	r.Methods("POST").Path(`/api/v1/message/file/tags`).Handler(setTagHandler)
	r.Methods("GET").Path(`/api/v1/message/file/travel`).Handler(fileTravelHandler)
	return r
}

func decodeFileTravelRequest(_ context.Context, r *http.Request) (interface{}, error) {
	err := r.ParseForm()
	if err != nil {
		return nil, err
	}
	id := r.Form.Get("id")
	if id == "" {
		return nil, errors.New("缺少id参数")
	}
	return fileTravelRequest{Id: id}, nil
}

func encodeFileTravelResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func decodeSetTagRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request setTagRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}
	// TODO 校验
	return request, nil
}

func encodeSetTagResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func decodeSearchFileRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request searchFileRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}
	// TODO 校验
	return request, nil
}

func encodeSearchFileResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func decodeAlarmMessageRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request alarmMessageRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}
	// TODO 校验
	return request, nil
}

func encodeAlarmMessageResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func decodeMessageContextRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request messageContextRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}
	// TODO 校验
	return request, nil
}

func encodeMessageContextResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func decodeMessageSearchRequest(_ context.Context, r *http.Request) (interface{}, error) {
	var request messageSearchRequest
	if err := json.NewDecoder(r.Body).Decode(&request); err != nil {
		return nil, err
	}

	// TODO 校验
	return request, nil
}

func encodeMessageSearchResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	return json.NewEncoder(w).Encode(response)
}

func errorEncoder(_ context.Context, err error, w http.ResponseWriter) {
	w.Header().Set("Content-Type", "application/json; charset=utf-8")
	_ = json.NewEncoder(w).Encode(map[string]string{"error": err.Error()})
}
